package com.example.jvm.jvm05.lesson36;

import com.example.jvm.jvm05.lesson31.MyObject;
import com.example.jvm.jvm05.lesson31.Student;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.openjdk.jol.datamodel.X86_32_DataModel;
import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.layouters.HotSpotLayouter;
import org.openjdk.jol.layouters.Layouter;

import java.util.concurrent.TimeUnit;

/**
 * @Description
 * @Date 2021/7/13
 * @Created by Jonathan
 */
@Slf4j
public class MarkWordTest {
    @Test
    public void test1() {
        Layouter l;
        l = new HotSpotLayouter(new X86_32_DataModel());
        MyObject o = new MyObject("111", new Student(), 111, 1, 1L);
//        log.info("十六进制：{}", Integer.toHexString(o.hashCode()));
        // 无锁
        log.info(ClassLayout.parseInstance(o, l).toPrintable());

    }

    @Test
    public void test2() throws InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        Layouter l;
        l = new HotSpotLayouter(new X86_32_DataModel());
        // 启动5秒后创建对象
        // 匿名偏向锁
        MyObject o = new MyObject("111", new Student(), 111, 1, 1L);
        log.info("threadId:{}", Thread.currentThread().getId());
        log.info(ClassLayout.parseInstance(o, l).toPrintable());
//        log.info("十六进制：{}", Integer.toHexString(o.hashCode()));

    }

    @Test
    public void test3() throws InterruptedException {
        Layouter l;
        l = new HotSpotLayouter(new X86_32_DataModel());
        MyObject o1 = new MyObject("111", new Student(), 111, 1, 1L);
        // 无锁
        log.info(ClassLayout.parseInstance(o1, l).toPrintable());
        log.info("-------------------分割线-------------------");
        TimeUnit.SECONDS.sleep(5);
        MyObject o2 = new MyObject("111", new Student(), 111, 1, 1L);
        log.info(ClassLayout.parseInstance(o2, l).toPrintable());
        // 启动5秒后创建对象
        // 匿名偏向锁
        log.info("threadId:{}", Thread.currentThread().getId());
        synchronized (o2) {
            // 偏向锁
            log.info(ClassLayout.parseInstance(o2, l).toPrintable());
        }
    }

    /**
     * 无锁-->(匿名)偏向锁-->轻量级
     */
    @Test
    public void test4() throws InterruptedException {
        MyObject o1 = new MyObject("111", new Student(), 111, 1, 1L);
        // 1.无锁
        log.info("无锁。。。");
        log.info(ClassLayout.parseInstance(o1).toPrintable());
        log.info("-------------------分割线-------------------");
        TimeUnit.SECONDS.sleep(5);
        MyObject o2 = new MyObject("111", new Student(), 111, 1, 1L);
        // 2.匿名偏向锁
        // 启动5秒后创建对象
        log.info("偏向锁有线程Id。。。");
        log.info(ClassLayout.parseInstance(o2).toPrintable());
        log.info("-------------------分割线-------------------");
        synchronized (o2) {
            // 3.偏向锁
            log.info(ClassLayout.parseInstance(o2).toPrintable());
            log.info("-------------------分割线-------------------");
        }
        new Thread(() -> {
            //4. 轻量级锁
            synchronized (o2) {
                log.info("轻量级锁。");
                log.info(ClassLayout.parseInstance(o2).toPrintable());
            }
        }, "thread-t1").start();
    }

    /**
     * 重量级锁
     */
    @Test
    public void test5() throws InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        MyObject o = new MyObject("111", new Student(), 111, 1, 1L);
        Thread t1 = new Thread(() -> {
            synchronized (o) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.info(ClassLayout.parseInstance(o).toPrintable());
                log.info("============t1结束运行。====================");
            }
        }, "t1");
        Thread t2 = new Thread(() -> {
            //4. 轻量级锁
            synchronized (o) {
                log.info("hashCode:{}", Integer.toHexString(o.hashCode()));
                log.info(ClassLayout.parseInstance(o).toPrintable());
                log.info("============t2运行结束。====================");
            }
        }, "t2");
        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
}
